package agent;

import java.util.ArrayList;

import processing.core.PVector;

public class FlockingBehavior extends Behavior{
	float attractRadius;
	float repelRadius;
	ArrayList<Agent> farNeighbors;
	ArrayList<Agent> nearNeighbors;
	
	FlockingBehavior(Main p, float farRadius, float nearRadius) {
		super(p);
		this.attractRadius = farRadius;
		this.repelRadius = nearRadius;
	}
	
	public void apply(Agent a) {
		super.apply(a);
		farNeighbors = p.getNeighbors(a, attractRadius);
		if (farNeighbors.size() > 0) {
			attract(a);
			adjustHeading(a);
		}
		nearNeighbors = p.getNeighbors(a, repelRadius);
		if (nearNeighbors.size() > 0) {
			repel(a);
		}
	}
	
	public void attract(Agent a) {
		PVector centerOfMass = new PVector(0,0);
		for (int i = 0; i < farNeighbors.size(); i++) {
			centerOfMass.add(farNeighbors.get(i).getCurrentPosition());
		}
		centerOfMass.div(farNeighbors.size());
		centerOfMass.sub(a.getCurrentPosition());
		centerOfMass.div(100);
		a.setVelocity(PVector.add(a.getCurrentVelocity(),centerOfMass));
	}
	
	public void repel(Agent a) {
		PVector centerOfMass = new PVector(0,0);
		for (int i = 0; i < nearNeighbors.size(); i++) {
			centerOfMass.add(nearNeighbors.get(i).getCurrentPosition());
		}
		centerOfMass.div(-1*nearNeighbors.size());
		centerOfMass.add(a.getCurrentPosition());
		a.setVelocity(PVector.add(a.getCurrentVelocity(),centerOfMass));
	}
	
	public void adjustHeading(Agent a) {
		PVector centerOfVelocity = new PVector(0,0);
		for (int i = 0; i < farNeighbors.size(); i++) {
			centerOfVelocity.add(farNeighbors.get(i).getCurrentVelocity());
		}
		centerOfVelocity.div(farNeighbors.size());
		centerOfVelocity.sub(a.getCurrentVelocity());
		centerOfVelocity.div(8.f);
		a.setVelocity(PVector.add(a.getCurrentVelocity(),centerOfVelocity));
	}

}
